<?php

namespace p5\objects;

use Memcache;
use Memcached;

/**
 * Created by PhpStorm.
 * User: simon
 * Date: 2015/11/23
 * Time: 9:40
 */
class MemcacheUtils
{

    public static function enabled()
    {
        global $configs;
        if (!array_key_exists("memcache_host", $configs)) {
            return false;
        }
        return class_exists("Memcache");
    }

    public static function stats($flag)
    {
        $mc = static::newClassInstance();
        if (empty($mc)) {
            return null;
        }
        return ($mc->getExtendedStats($flag));
    }

    /**
     * @param $key
     * @param $object
     * @param bool|false $compress
     * @param int $timeLong second
     */
    public static function cache($key, $object, $compress = false, $timeLong = 0)
    {
        $new_key = self::to_project_key($key);
        $mc = static::newClassInstance();
        if (empty($mc)) {
            return;
        }
        $mc->delete($new_key, 0);
        if (class_exists("Memcache")) {
            $mc->add($new_key, $object, $compress, $timeLong);
        } else if (class_exists("Memcached")) {
            $mc->add($new_key, $object, $timeLong);
        }
        static::closeInstance($mc);
        return;
    }

    public static function replace($key, $object, $compress = false, $timeLong = 0)
    {
        self::cache($key, $object, $compress, $timeLong);
        return;
    }

    public static function exists($key)
    {
        return self::get($key, false) !== false;
    }

    public static function get($key, $obj = false, $compress = false, $timeLong = 0)
    {
        $new_key = self::to_project_key($key);
        $mc = static::newClassInstance();
        if (empty($mc)) {
            return null;
        }
        $object = $mc->get($new_key);
        static::closeInstance($mc);

        if ($object == false && $obj != false) {
            self::cache($key, $obj, $compress, $timeLong);
            return $obj;
        }
        return $object;
    }

    private static function newClassInstance()
    {
        global $configs, $logger;
        if (!isset($configs)) {
            static::debug("没有配置 Memcache");
            return null;
        }
        if (!isset($configs["memcache_host"]) || !isset($configs["memcache_port"])) {
            static::debug("没有配置 Memcache");
            return null;
        }
        if (class_exists("Memcache")) {
            $mc = new Memcache();
            $mc->connect($configs["memcache_host"], $configs["memcache_port"]);
            return $mc;
        }
        if (class_exists("Memcached")) {
            $mc = new Memcached("global");
            $mc->addServer($configs["memcache_host"], $configs["memcache_port"]);
            return $mc;
        }
        if (isset($logger)) {
            $logger->error("尚未安装php的memcache插件");
        }
        return null;
    }

    private static function debug($info)
    {
        global $logger;
        if (isset($logger)) {
            $logger->debug($info);
        }
    }

    private static function closeInstance($mc)
    {
        if (class_exists("Memcache")) {
            $mc->close();
        } else {
            // 不关闭
            // Memcached::quit();
        }
    }

    public static function delete($key, $delay = 0)
    {
        $new_key = self::to_project_key($key);
        $mc = static::newClassInstance();
        if (empty($mc)) {
            return;
        }
        $mc->delete($new_key, $delay);
        static::closeInstance($mc);
    }

    public static function flush()
    {
        $mc = static::newClassInstance();
        if (empty($mc)) {
            return;
        }
        $mc->flush();
        static::closeInstance($mc);
    }

    public static function get_sql_result($sqlstr, $compress = 0, $timeLong = 0, $db_id = "default")
    {
        $result = self::get($sqlstr);
        if ($result == false) {
            $result = DBUtils::query_result($sqlstr, $db_id);
            //	print "fetch result <br>";
            if (is_array($result) && count($result) > 0) {
                self::cache($sqlstr, $result, $compress, $timeLong);
                return $result;
            } else {
                return false;
            }
        } else {
            return ($result);
        }
    }

//直接在MEM里存储单数据 后续完善跨不同数据库下的MEM存储
    public static function get_col00_result($sqlstr, $compress = 0, $timeLong = 0, $db_id = "default")
    {
        $result = self::get($sqlstr);
        if (!$result) {
            $result = DBUtils::query_col00($sqlstr, $db_id);
            $object = $result;
            self::cache($sqlstr, $object, $compress, $timeLong);
            return $result;
        } else {
            return ($result);
        }
    }

    public static function map_get_result($sqlstr, $compress = 0, $timeLong = 0, $db_id = "default")
    {
        $db_id = empty($db_id) ? "default" : $db_id;
        $result = self::get($sqlstr);
        if ($result == false) {
            $result = DBUtils::query_into_map($sqlstr, $db_id);
            $object = $result;
            if (is_array($object) && count($object) > 0) {
                self::cache($sqlstr, $object, $compress, $timeLong);
            } else {
                // error("mem_map_get_sql_result is not valid result : ".$sqlstr) ;
            }
            return $result;
        } else {
            return ($result);
        }
    }

    public static function map_get($sqlstr, $compress = 0, $timeLong = 120, $db_id = "default")
    {
        $db_id = empty($db_id) ? "default" : $db_id;
        $result = self::get($sqlstr);
        if ($result == false) {
            $result = DBUtils::query_into_hash($sqlstr, $db_id);
            //	print "fetch into map <br>";
            $object = $result;
            if (is_array($object) && count($object) > 0) {
                self::cache($sqlstr, $object, $compress, $timeLong);
            } else {
                // error("mem_map_get_sql_result is not valid result : ".$sqlstr) ;
            }
            return $result;
        } else {
            return ($result);
        }
    }

    public static function increment($key, $object = 1, $compress = false, $timeLong = 0)
    {
        $result = self::get($key);
        if (!$result) {
            self::cache($key, 1, $compress, $timeLong);
            return 1;
        }
        $result += 1;
        self::replace($key, $result, $compress, $timeLong);
        return $result;
    }

    public static function to_project_key($key)
    {
        global $configs;
        if (array_key_exists("system_code", $configs)) {
            return $configs["system_code"] . ":" . md5($key);
        }
        return md5($configs["system_name"]) . ":" . md5($key);
    }

}